home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tech Arsenal 1
/
Tech Arsenal (Arsenal Computer).ISO
/
tek-13
/
xvisrc.zip
/
MOUSE.C
< prev
next >
Wrap
C/C++ Source or Header
|
1992-07-28
|
5KB
|
248 lines
/* Copyright (c) 1990,1991,1992 Chris and John Downey */
#ifndef lint
static char *sccsid = "@(#)mouse.c 2.1 (Chris & John Downey) 7/29/92";
#endif
/***
* program name:
xvi
* function:
PD version of UNIX "vi" editor, with extensions.
* module name:
mouse.c
* module function:
Machine-independent mouse interface routines.
* history:
STEVIE - ST Editor for VI Enthusiasts, Version 3.10
Originally by Tim Thompson (twitch!tjt)
Extensive modifications by Tony Andrews (onecom!wldrdg!tony)
Heavily modified by Chris & John Downey
***/
#include "xvi.h"
/*
* Find the Line corresponding to a given physical screen row.
*
* Also return (in *pstartrow) the physical screen row on which that
* Line starts.
*/
static Line *
findline(wp, row, pstartrow)
Xviwin *wp;
register int row;
int *pstartrow;
{
register int lposn;
int maxrow;
register Line *lp;
Line *lastline;
lp = wp->w_topline;
lastline = wp->w_buffer->b_lastline;
lposn = wp->w_winpos;
maxrow = wp->w_cmdline;
for (;;) {
register int newposn;
newposn = lposn + LONG2INT(plines(wp, lp));
if (
(
/*
* If we've found the right line ...
*/
row >= lposn
&&
row < newposn
)
||
(
/*
* ... or we've got to the end of the buffer ...
*/
lp->l_next == wp->w_buffer->b_lastline
)
||
(
/*
* ... or we're at the bottom of the window ...
*/
newposn >= maxrow
)
) {
/*
* ... we return this line.
*/
*pstartrow = lposn;
return lp;
}
lposn = newposn;
lp = lp->l_next;
}
}
/*
* Move the text cursor as near as possible to the given physical
* screen co-ordinates.
*/
static void
setcursor(wp, row, col)
Xviwin *wp;
int row; /* row where mouse was clicked */
int col; /* column where mouse was clicked */
{
int startrow; /* row at which line starts */
int vcol; /* virtual column */
Line *lp; /* logical line corresponding to row */
lp = findline(wp, row, &startrow);
vcol = col + ((row - startrow) * wp->w_ncols);
move_cursor(wp, lp, 0);
coladvance(wp, (wp->w_curswant = vcol));
}
/*
* Find the window a given physical screen row is in.
*/
static Xviwin *
findwin(row)
register int row;
{
register Xviwin *wp;
wp = curwin;
for (;;) {
if (wp->w_winpos <= row && row <= wp->w_cmdline) {
/*
* We've found the right window.
*/
return wp;
}
if ((wp = next_window(wp)) == curwin) {
/*
* This can't happen: the mouse isn't in any
* window.
*/
return NULL;
}
}
}
/*
* Handle mouse drag event.
*/
void
mousedrag(row1, row2, col1, col2)
int row1, row2, col1, col2;
{
if (State == NORMAL && row1 != row2 && row1 < Rows - 1) {
Xviwin *wp;
if ((wp = findwin(row1)) == NULL) {
/*
* This can't happen.
*/
return;
}
if (wp->w_cmdline == row1) {
unsigned savecho;
savecho = echo;
echo &= ~e_CHARUPDATE;
(void) move_sline(wp, row2 - row1);
echo = savecho;
move_cursor_to_window(curwin);
update_all();
cursupdate(curwin);
wind_goto(curwin);
}
}
}
/*
* This function is called by the (obviously machine-dependent) mouse
* event handling code when a mouse button is pressed & released.
*
* The algorithm we use here is semantically complicated, but seems to
* be fairly intuitive in actual use.
*/
void
mouseclick(row, col)
register int row; /* row the mouse cursor is in */
int col; /* column the mouse cursor is in */
{
register Xviwin *wp;
if (State != NORMAL) {
return;
}
/*
* First find which window the mouse is in.
*/
if ((wp = findwin(row)) == NULL) {
/*
* This can't happen.
*/
return;
}
if (wp != curwin) {
/*
* The window the mouse is in isn't the current window.
* Make it the current window.
*/
curwin = wp;
curbuf = wp->w_buffer;
}
if (row == wp->w_cmdline) {
/*
* If the mouse is on the status line of any window,
* we update the information on the status line. This
* applies whether or not it was already the current
* window.
*/
show_file_info(wp);
} else {
/*
* Move the cursor as near as possible to where the
* mouse was clicked.
*/
setcursor(wp, row, col);
/*
* If the window has at least 2 text rows, and ...
*/
if (wp->w_nrows > 2) {
if (row == wp->w_winpos) {
/*
* ... we're on the top line of the
* window - scroll down ...
*/
scrolldown(wp, (unsigned) 1);
update_window(wp);
} else if (row == wp->w_cmdline - 1) {
/*
* ... or we're on the bottom line of
* the window - scroll up ...
*/
scrollup(wp, (unsigned) 1);
update_window(wp);
}
}
}
/*
* Make sure physical screen and cursor position are updated.
*/
cursupdate(wp);
wind_goto(wp);
}